<template>
  <a-card :body-style="{ height: 'calc(100vh - 125px)' }">
    <div class="w-full h-full flex justify-between">
      <!-- 按文件来源将文件分类 -->
      <a-row class="h-full border-r pr-3">
        <a-list class="w-[240px]" hoverable size="small">
          <a-list-item
              :class="searchForm.fileSource === null ? 'file-source-active' : ''"
              class="cursor-pointer"
              @click="fileSourceClick(null)"
          >全部文件
          </a-list-item
          >
          <a-list-item
              v-for="(d, index) in dicts[proxy.DICT.fileSource]"
              :key="index"
              :class="searchForm.fileSource === d.dictKey ? 'file-source-active' : ''"
              class="cursor-pointer"
              @click="fileSourceClick(d.dictKey)"
          >
            {{ d.dictValue }}
          </a-list-item>
        </a-list>
      </a-row>

      <!-- 文件数据 -->
      <a-row class="w-full flex flex-1 flex-col pl-3 overflow-x-auto overflow-y-hidden">
        <!-- 查询条件 -->
        <a-row v-if="showSearchRow" class="w-full">
          <a-form :model="searchForm" label-align="left" layout="inline" size="small">
            <a-form-item field="fileName" label="文件名称">
              <a-input v-model="searchForm.fileName" placeholder="文件名称"/>
            </a-form-item>
            <a-form-item field="status" label="文件状态">
              <a-select v-model="searchForm.status" allow-clear placeholder="文件状态">
                <a-option
                    v-for="(d, index) in dicts[proxy.DICT.commonNumberStatus]"
                    :key="index"
                    :label="d.dictValue"
                    :value="d.dictKey"
                />
              </a-select>
            </a-form-item>
          </a-form>
          <a-row class="w-full mt-2" justify="center">
            <a-space>
              <a-button type="primary" @click="getPageList(false)">
                <template #icon>
                  <icon-search/>
                </template>
                <template #default>查询</template>
              </a-button>
              <a-button @click="getPageList(true)">
                <template #icon>
                  <icon-sync/>
                </template>
                <template #default>重置</template>
              </a-button>
            </a-space>
          </a-row>
        </a-row>

        <!-- 分割线 -->
        <a-divider v-if="showSearchRow" class="mt-2"/>

        <!-- 数据操作区 -->
        <a-row class="w-full flex justify-between">
          <a-space>
            <!-- 文件选择组件演示 - 可供其他页面调用 -->
            <a-button size="small" type="primary" @click="selectFileBtnClick()">
              <template #default>文件选择组件演示</template>
            </a-button>
            <!-- 添加批量删除按钮 -->
            <a-button
                :disabled="selectedRowKeys.length === 0"
                :loading="batchDeleting"
                size="small"
                status="danger"
                type="primary"
                @click="batchDeleteBtnClick"
            >
              <template #icon>
                <icon-delete/>
              </template>
              <template #default>{{ batchDeleting ? "删除中" : "批量删除" }}</template>
            </a-button>
          </a-space>
          <a-space>
            <!-- 刷新 -->
            <a-button shape="circle" size="small" @click="getPageList(false)">
              <template #icon>
                <icon-refresh/>
              </template>
            </a-button>
            <!-- 收缩/展开 -->
            <a-button shape="circle" size="small" @click="showSearchRow = !showSearchRow">
              <template #icon>
                <icon-caret-up v-if="showSearchRow"/>
                <icon-caret-down v-else/>
              </template>
            </a-button>
          </a-space>
        </a-row>

        <!-- 数据展示区 -->
        <a-row class="w-full flex-1 mt-3 overflow-y-auto">
          <a-table
              v-model:selectedKeys="selectedRowKeys"
              :columns="datatable.columns"
              :data="datatable.records"
              :loading="datatable.loading"
              :pagination="false"
              :row-selection="rowSelection"
              :scroll="{ minWidth: 600, y: '100%' }"
              class="w-[100%]"
              row-key="fileId"
              table-layout-fixed
          >
            <!-- 文件名称 -->
            <template #fileName="{ record }">
              <a-tooltip :content="record.fileName">
                <div class="w-[190px] flex items-center truncate">
                  <!-- 文件类型图标 -->
                  <img
                      v-if="record.fileType.includes('image')"
                      :src="getImageUrl(record, '../../../assets/file-icon/image.svg')"
                      alt=""
                      style="width: 20px"
                  />
                  <img
                      v-else
                      :src="getImageUrl(record, '../../../assets/file-icon/unknown.svg')"
                      alt=""
                      style="width: 20px"
                  />
                  <!-- 文件名称，改为a-link组件 -->
                  <a-link class="ml-2 truncate" hoverable @click="previewFile(record)">
                    {{ record.fileName }}
                  </a-link>
                </div>
              </a-tooltip>
            </template>
            <!-- 文件大小 -->
            <template #fileSize="{ record }">
              {{ formatFileSize(record.fileSize) }}
            </template>
            <!-- 文件来源 -->
            <template #fileSource="{ record }">
              <dict-convert
                  :dict-data="dicts[proxy.DICT.fileSource]"
                  :dict-key="record.fileSource"
              />
            </template>
            <!-- 存储方式 -->
            <template #storageId="{ record }">
              <dict-convert
                  :dict-data="dicts[proxy.DICT.storageList]"
                  :dict-key="record.storageId"
              />
            </template>
            <!-- 文件状态 -->
            <template #status="{ record }">
              <dict-convert
                  :dict-data="dicts[proxy.DICT.commonNumberStatus]"
                  :dict-key="record.status"
              />
            </template>
            <!-- 操作 -->
            <!-- 操作 -->
            <template #operation="{ record }">
              <a-button
                  v-perm="['basic:file:download']"
                  size="mini"
                  type="text"
                  @click="downloadBtnClick(record)"
              >
                <template #icon>
                  <icon-download/>
                </template>
                <template #default>下载</template>
              </a-button>
              <a-popconfirm content="确认要删除吗?" @ok="deleteBtnOkClick(record.fileId)">
                <a-button
                    v-perm="['basic:file:delete']"
                    :loading="record.deleting"
                    size="mini"
                    status="danger"
                    type="text"
                >
                  <template #icon>
                    <icon-delete/>
                  </template>
                  <template #default>{{ record.deleting ? "删除中" : "删除" }}</template>
                </a-button>
              </a-popconfirm>
            </template>
          </a-table>
        </a-row>

        <!-- 分页 -->
        <a-row class="w-full flex justify-end mt-2">
          <pagination
              v-if="datatable.total > 0"
              v-model:page-num="searchForm.pageNum"
              v-model:page-size="searchForm.pageSize"
              :total="datatable.total"
              @pagination="getPageList(false)"
          />
        </a-row>
      </a-row>
    </div>

    <!-- 文件选择组件演示 -->
    <a-modal
        v-model:visible="modal.visible"
        :esc-to-close="false"
        :footer="false"
        :mask-closable="false"
        draggable
        width="60%"
    >
      <template #title>{{ modal.title }}</template>
      <file-select
          v-if="modal.visible"
          :file-type="modal.fileType"
          :limit="modal.limit"
          @cancel="onCancel"
          @ok="onOk"
      />
    </a-modal>
  </a-card>
</template>

<script setup>
import {getCurrentInstance, reactive, ref} from "vue";
import {batchDeleteFileApi, deleteFileApi, getPageFileListApi} from "~/api/basic/file.js";
import FileSelect from "~/pages/basic/file/FileSelect.vue";
import {fileType} from "~/utils/sys.js";
import {Modal} from "@arco-design/web-vue";

// 时间戳，用于刷新图片缓存
const timestamp = ref(Date.now());

// 添加选中行的状态管理
const selectedRowKeys = ref([]);
const selectedRows = ref([]);
// 批量删除按钮加载状态
const batchDeleting = ref(false);

// 表格行选择配置
const rowSelection = reactive({
  type: "checkbox",
  showCheckedAll: true,
  onlyCurrent: false,
  onChange: (rowKeys, rows) => {
    // 移除console.log，直接更新选中行的状态
    selectedRowKeys.value = rowKeys;
    selectedRows.value = rows;
  },
});

// 批量删除按钮点击
const batchDeleteBtnClick = () => {
  if (selectedRowKeys.value.length === 0) {
    return;
  }

  Modal.warning({
    title: "批量删除确认",
    content: `确定要删除选中的 ${selectedRowKeys.value.length} 个文件吗？此操作不可恢复！`,
    okText: "确认删除",
    cancelText: "取消",
    onOk: () => {
      // 设置批量删除按钮的加载状态
      batchDeleting.value = true;
      // 设置选中记录的删除中状态
      selectedRows.value.forEach((row) => {
        const record = datatable.records.find((item) => item.fileId === row.fileId);
        if (record) {
          record.deleting = true;
        }
      });

      // 调用批量删除API
      batchDeleteFileApi(selectedRowKeys.value)
          .then(() => {
            proxy.$msg.success(`成功删除 ${selectedRowKeys.value.length} 个文件`);
            // 清空选择
            selectedRowKeys.value = [];
            selectedRows.value = [];
            // 刷新列表
            getPageList();
          })
          .catch(() => {
            // 删除失败时，恢复删除中状态
            selectedRows.value.forEach((row) => {
              const record = datatable.records.find((item) => item.fileId === row.fileId);
              if (record) {
                record.deleting = false;
              }
            });
          })
          .finally(() => {
            // 无论成功或失败，都需要重置批量删除按钮的加载状态
            batchDeleting.value = false;
          });
    },
  });
};

// 获取图片URL，添加时间戳防止缓存
const getImageUrl = (record, defaultIcon) => {
  // 如果是图片类型且有预览URL
  if (record.fileType && record.fileType.includes("image") && record.fileUrl) {
    const separator = record.fileUrl.includes("?") ? "&" : "?";
    // 使用文件ID作为唯一标识，避免所有图片使用相同的时间戳
    return `${record.fileUrl}${separator}_id=${record.fileId}&_t=${
        record.updateTime || timestamp.value
    }`;
  }
  // 返回默认图标
  return defaultIcon;
};

// 格式化文件大小为易读的形式（KB、MB、GB等）
const formatFileSize = (size) => {
  if (!size || size <= 0) {
    return "0 B";
  }

  const units = ["B", "KB", "MB", "GB", "TB"];
  let index = 0;
  let formattedSize = size;

  while (formattedSize >= 1024 && index < units.length - 1) {
    formattedSize /= 1024;
    index++;
  }

  // 保留两位小数
  return `${formattedSize.toFixed(2)} ${units[index]}`;
};

/********************** 文件选择组件演示 **********************/
const modal = reactive({
  //是否显示
  visible: false,
  //模态框标题
  title: "文件选择",
  //文件类型
  fileType: "",
  //可以选择几个文件
  limit: 1,
});
//模态框 -> 确认
const onOk = (selectedFiles) => {
  modal.visible = false;
  // 刷新文件列表
  getPageList(false);
};
//模态框 -> 取消
const onCancel = () => {
  modal.visible = false;
};
//点击选择
const selectFileBtnClick = () => {
  modal.visible = true;
  modal.fileType = fileType.image.key;
};
/********************** 文件选择组件演示结束 **********************/

//全局实例
const {proxy} = getCurrentInstance();
//加载字典
const dicts = proxy.LoadDicts([
  proxy.DICT.commonNumberStatus,
  proxy.DICT.fileSource,
  proxy.DICT.storageList,
]);
//是否展示搜索区域
const showSearchRow = ref(true);
//搜索参数表单
const searchForm = reactive({
  //文件来源
  fileSource: null,
  //文件名称
  fileName: null,
  //文件状态
  status: null,
  //页码
  pageNum: 1,
  //条数
  pageSize: 10,
});
//数据列表
const datatable = reactive({
  //列配置
  columns: [
    {
      title: "文件名称",
      dataIndex: "fileName",
      align: "center",
      width: 100,
      ellipsis: true,
      tooltip: true,
      slotName: "fileName",
    },
    {
      title: "文件大小",
      dataIndex: "fileSize",
      slotName: "fileSize",
      align: "center",
      width: 100,
      ellipsis: true,
      tooltip: true,
    },
    {
      title: "文件来源",
      dataIndex: "fileSource",
      slotName: "fileSource",
      align: "center",
      width: 150,
      ellipsis: true,
      tooltip: true,
    },
    {
      title: "存储方式",
      dataIndex: "storageId",
      slotName: "storageId",
      align: "center",
      width: 120,
      ellipsis: true,
      tooltip: true,
    },
    {
      title: "文件状态",
      dataIndex: "status",
      slotName: "status",
      align: "center",
      width: 100,
      ellipsis: true,
      tooltip: true,
    },
    {
      title: "创建时间",
      dataIndex: "createTime",
      align: "center",
      width: 160,
      ellipsis: true,
      tooltip: true,
    },
    // {
    //   title: "备注",
    //   dataIndex: "remark",
    //   align: "center",
    //   width: 200,
    //   ellipsis: true,
    //   tooltip: true,
    // },
    {title: "操作", slotName: "operation", align: "center", width: 160, fixed: "right"},
  ],
  //加载
  loading: false,
  //数据列表
  records: [],
  //总条数
  total: 0,
});
//查询数据列表
const getPageList = (isReset = false) => {
  if (isReset) {
    searchForm.fileName = null;
    searchForm.status = null;
    searchForm.pageNum = 1;
    searchForm.pageSize = 10;
  }
  datatable.loading = true;
  getPageFileListApi(searchForm)
      .then((res) => {
        // 为每条记录添加删除中状态属性
        datatable.records = res.records.map((item) => ({
          ...item,
          deleting: false,
        }));
        datatable.total = res.total;
      })
      .finally(() => {
        datatable.loading = false;
      });
};
//表格行数据 "下载" -> 点击
const downloadBtnClick = (record) => {
  window.open(record.fileUrl, "_blank");
};

//预览文件
const previewFile = (record) => {
  // 如果是图片类型，直接在新窗口打开
  if (record.fileType && record.fileType.includes("image")) {
    window.open(record.fileUrl, "_blank");
  } else {
    // 对于其他类型文件，也可以尝试预览
    // 如果浏览器无法预览，会自动下载
    window.open(record.fileUrl, "_blank");
  }
};

//表格行数据 "删除" -> 确认
const deleteBtnOkClick = (fileId) => {
  // 找到当前正在删除的记录
  const record = datatable.records.find((item) => item.fileId === fileId);
  if (record) {
    // 设置删除中状态
    record.deleting = true;
  }

  deleteFileApi(fileId)
      .then(() => {
        proxy.$msg.success(proxy.operationType.delete.success);
        //刷新列表
        getPageList();
      })
      .catch(() => {
        // 删除失败时，恢复删除中状态
        if (record) {
          record.deleting = false;
        }
      });
};

//文件来源 -> 点击
const fileSourceClick = (fileSource) => {
  //fileSource = null，查询全部
  searchForm.fileSource = fileSource;
  //查询数据列表
  getPageList();
};

//查询数据列表
getPageList();
</script>
<style scoped>
/* 文件来源选中 */
.file-source-active {
  background-color: var(--color-fill-1);
  color: rgb(var(--arcoblue-6));
}
</style>
